<html>

<head>
  <meta charset="utf8">
  <title>3D in WebGL</title>
  <link type="text/css" href="../../resources/webgl-tutorials.css" rel="stylesheet" />
  <style>
    canvas {
      border: 1px solid black;
    }
  </style>
</head>

<body>
  <div id="info">
    <a href="https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-2d-vs-3d-library.html" target="_blank">WebGL -
      光栅化 vs 三维库</a>
  </div>
  <h1 class="description">3D in WebGL</h1>
  <p><canvas id="c"></canvas></p>
  <p class="description"><a href="3d-in-canvas.html">compare to 3D in Canvas</a></p>
</body>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position;
uniform mat4 u_worldViewProjection;

void main() {
   gl_Position = u_worldViewProjection * a_position;
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
void main() {
   gl_FragColor = vec4(0,0,0,1);
}
</script>
<!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See http://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html
and http://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="../../resources/webgl-utils.js"></script>
<script src="../../resources/webgl-lessons-helper.js"></script>
<!-- you can and should delete this script. it is only used on the site to help with errors -->
<script src="../../resources/m4.js"></script>
<script>
  "use strict";

  function main() {
    var cubeVertices = [
      -1, -1, -1,
      1, -1, -1,
      1, 1, -1,
      -1, 1, -1,
      -1, -1, 1,
      1, -1, 1,
      1, 1, 1,
      -1, 1, 1,
    ];
    var indices = [
      0, 1,
      1, 2,
      2, 3,
      3, 0,
      4, 5,
      5, 6,
      6, 7,
      7, 4,
      0, 4,
      1, 5,
      2, 6,
      3, 7,
    ];

    var canvas = document.getElementById("c");
    var gl = canvas.getContext("webgl");
    if (!gl) {
      return;
    }

    var program = webglUtils.createProgramFromScripts(
      gl, ["2d-vertex-shader", "2d-fragment-shader"]);
    gl.useProgram(program);

    var positionLoc = gl.getAttribLocation(program, "a_position");
    var worldViewProjectionLoc =
      gl.getUniformLocation(program, "u_worldViewProjection");

    var buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array(cubeVertices),
      gl.STATIC_DRAW);
    gl.enableVertexAttribArray(positionLoc);
    gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);

    var buffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
    gl.bufferData(
      gl.ELEMENT_ARRAY_BUFFER,
      new Uint16Array(indices),
      gl.STATIC_DRAW);

    function render(clock) {
      clock *= 0.001;

      var scale = 4;

      webglUtils.resizeCanvasToDisplaySize(gl.canvas, window.devicePixelRatio);

      gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

      gl.clear(gl.COLOR_BUFFER_BIT);

      var fieldOfView = Math.PI * 0.25;
      var aspect = canvas.clientWidth / canvas.clientHeight;
      var projection = m4.perspective(fieldOfView, aspect, 0.0001, 500);
      var radius = 5;
      var eye = [
        Math.sin(clock) * radius,
        2,
        Math.cos(clock) * radius];
      var target = [0, 0, 0];
      var up = [0, 1, 0];
      var camera = m4.lookAt(eye, target, up);
      var view = m4.inverse(camera);

      var worldViewProjection = m4.multiply(projection, view);
      gl.uniformMatrix4fv(
        worldViewProjectionLoc, false, worldViewProjection);

      gl.drawElements(gl.LINES, indices.length, gl.UNSIGNED_SHORT, 0);
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
  }

  main();
</script>

</html>